package com.example.util;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 线程池配置
 * <p>
 * CPU密集型：核心线程数 = CPU 核数 + 1
 * IO密集型：核心线程数 = CPU 核数 * 2
 * @Author: mingtian
 * @CreateDate: 2020/11/12 9:59
 * @Version: 1.0
 */
public class ThreadPoolUtil {

    /**
     * 打印日志
     */
    private static Logger logger = LoggerFactory.getLogger(ThreadPoolUtil.class);

    /**
     * 默认 CPU 核心数
     */
    private static int threadPoolSize = 0;

    static {
        // 获取服务器 CPU 核心数
        threadPoolSize = Runtime.getRuntime().availableProcessors();
        logger.info("服务器 CPU 核心数量:{}", threadPoolSize);
    }

    public static int getThreadPoolSize() {
        return threadPoolSize;
    }

    /**
     * 线程工厂，用来创建线程
     */
    private static ThreadFactory build = new ThreadFactoryBuilder().setNameFormat("my-redis-pool-%d").build();

    /**
     * 设置线程池核心参数(IO 密集型) 核心线程数 = CPU 核数 * 2
     */
    private static ThreadPoolExecutor threadPoolExecutorIO =
            new ThreadPoolExecutor(threadPoolSize, threadPoolSize * 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2000), build, new ThreadPoolExecutor.DiscardOldestPolicy());

    /**
     * 设置线程池核心参数(IO 密集型) 核心线程数 = CPU 核数 * 2
     */
    private static ThreadPoolExecutor threadPoolExecutorIOTest =
            new ThreadPoolExecutor(threadPoolSize, threadPoolSize * 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), build, new ThreadPoolExecutor.DiscardOldestPolicy());


    /**
     * 设置线程池核心参数(CPU 密集型) 核心线程数 = CPU 核数 + 1 //  核心线程数 = CPU 核数 + 1
     */
    private static ThreadPoolExecutor threadPoolExecutorCPU =
            new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2000), build, new ThreadPoolExecutor.DiscardOldestPolicy());

    /**
     * 返回IO线程池对象
     *
     * @return
     */
    public static ThreadPoolExecutor getThreadPoolExecutorIO() {
        return threadPoolExecutorIO;
    }

    /**
     * 返回CPU线程池对象
     *
     * @return
     */
    public static ThreadPoolExecutor getThreadPoolExecutorCPU() {
        return threadPoolExecutorCPU;
    }

    public static class sendMessage implements Runnable {
        @Override
        public void run() {
            logger.info("发送消息测试");
        }
    }

    public static void main(String[] args) {
        logger.info("开始测试....");
        for (int i = 0; i < 5; i++) {
            ThreadPoolUtil.sendMessage sendMessage = new ThreadPoolUtil.sendMessage();
            threadPoolExecutorIOTest.execute(sendMessage);
        }
        logger.info("测试结束....");
    }

}